package cn.virens.common.project.generator;


import cn.virens.common.util.core.Assert;
import cn.virens.common.util.exception.APIException;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.text.StrUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class AbstrExampleGenerator {
    public void mainRun(String[] args) throws InterruptedException, IOException {
        Scanner scanner = new Scanner(System.in);

        List<String> sql = wait(scanner);

        String tableName = "";

        boolean tableFlag = false;
        boolean selectFlag = false;

        List<String[]> joinList = new ArrayList<>();
        List<String> selectList = new ArrayList<>();

        // 对输入的SQL内容进行解析-------------------------------------------------------------------
        for (String line : sql) {
            if (StrUtil.equalsIgnoreCase(line, "SELECT")) {
                selectFlag = true;

                continue;
            }

            if (StrUtil.equalsIgnoreCase(line, "FROM")) {
                selectFlag = false;
                tableFlag = true;

                continue;
            }

            if (tableFlag) {
                tableFlag = false;
                tableName = StrUtil.trim(line);
            } else if (StrUtil.contains(line, " JOIN ")) {
                joinList.add(formatJoin(StrUtil.trim(line)));
            } else if (selectFlag && StrUtil.isNotEmpty(line)) {
                selectList.add(formatField(StrUtil.trim(line)));
            }
        }

        // 清除输入内容，防止复制出现干扰-----------------------------------------------------------------
        for (int i = 0; i < 100; i++) {
            System.out.println();
        }

        // 输出查询条件构造器--------------------------------------------------------------------------
        System.out.print("Example example = Example.newInstance().asc(\"");
        System.out.print(StrUtil.trim(tableName));
        System.out.println(".id\");");

        // 输出查询字段列表---------------------------------------------------------------------------
        for (String select : pasreField(selectList)) {
            System.out.println(select);
        }

        // 输出连表规则------------------------------------------------------------------------------
        for (String[] strings : Assert.isNull(joinList)) {
            if (strings != null && "INNER".equals(strings[0])) {
                System.out.print("example.inner(\"");
            } else {
                System.out.print("example.left(\"");
            }

            System.out.print(strings[1]);
            System.out.print("\", c -> c.andCondition(\"");
            System.out.print(strings[2]);
            System.out.println("\"));");
        }
    }

    protected String[] formatJoin(String line) {
        String[] answer = new String[3];

        if (StrUtil.contains(line, "INNER JOIN")) {
            answer[0] = "INNER";
        } else {
            answer[0] = "LEFT";
        }

        String str0 = StrUtil.subAfter(line, " ON ", false);
        String str1 = StrUtil.subBefore(line, " ON ", false);
        String str2 = StrUtil.subAfter(str1, " JOIN ", false);

        answer[1] = str2;
        answer[2] = str0;

        return answer;
    }

    protected List<String> pasreField(List<String> select) {
        List<String> answer = new ArrayList<>();

        for (List<String> list : distributionField(select, 100)) {
            StringBuilder builder = new StringBuilder();
            builder.append("example.addSelectColumns(");

            for (String temps : list) {
                builder.append(", \"");
                builder.append(temps);
                builder.append("\"");
            }

            builder.deleteCharAt(25);
            builder.deleteCharAt(25);
            builder.append(");");

            answer.add(builder.toString());
        }

        return CollUtil.sort(answer, (a, b) -> {
            return Integer.compare(a.length(), b.length());
        });
    }

    /**
     * 均匀分配待查询字段列表
     */
    protected List<List<String>> distributionField(List<String> list, int max) {
        list.sort((a, b) -> Integer.compare(b.length(), a.length()));

        List<List<String>> answer = new ArrayList<>();

        while (list != null && !list.isEmpty()) {
            List<String> temp = new ArrayList<>();

            String line = list.remove(0);

            boolean skip = true;
            int total = 0;

            total += line.length();
            temp.add(line);

            do {
                skip = true;

                for (int i = 0; i < list.size(); i++) {
                    String b = list.get(i);
                    if (b == null || b.isEmpty()) {
                        continue;
                    }

                    if (total + b.length() < max) {
                        String s = list.remove(i);

                        total += s.length();
                        temp.add(s);
                        i--;

                        skip = false;
                    }
                }
            } while (!skip && !list.isEmpty());

            answer.add(temp);
        }

        return answer;
    }

    /**
     * 均匀分配待查询字段列表
     */
    protected List<List<String>> distributionField1(List<String> list, int max) {
        List<List<String>> answer = new ArrayList<>();

        while (list != null && !list.isEmpty()) {
            List<String> temp = new ArrayList<>();

            String line = list.remove(0);

            boolean skip = true;
            int total = 0;

            total += line.length();
            temp.add(line);

            do {
                skip = true;

                for (int i = 0; i < list.size(); i++) {
                    String b = list.get(i);
                    if (b == null || b.isEmpty()) {
                        continue;
                    }

                    if (total + b.length() < max) {
                        String s = list.remove(i);

                        total += s.length();
                        temp.add(s);
                        i--;

                        skip = false;
                    }
                }
            } while (!skip && !list.isEmpty());

            answer.add(temp);
        }

        return answer;
    }

    protected String formatField(String sql) throws APIException {
        return StrUtil.subBefore(sql, ",", false);//
    }

    protected List<String> wait(Scanner reader) throws APIException {
        List<String> list = new ArrayList<>();

        while (reader != null && reader.hasNext()) {
            String l = reader.nextLine();

            if ("END".equals(l.toUpperCase())) {
                return list;//
            }

            list.add(l);
        }

        return list;
    }
}
